﻿using Example.Modbus.Kernel;
using Microsoft.Extensions.Logging;
using SuperSocket.Command;
using Xph.Sag.Kernel;

//                01 03 20 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 8C 45
// 环境数据:       01 03 00 40 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 6B DA
// 通道3的温度:    01 03 02 7F FF D8 34
//  +19.5 C°     01 03 02 00 C3 F8 15
//  -19.5 C°     01 03 02 FF 3D 38 65
//                     01 03 00 08 0B 08 1F 0B 00 0A 01 01 98 E0
//设备编号:        01 03 00 60 00 04 0E 06 0C 01 82 DD
namespace Example.Modbus.Command;

[Command(Name = "ReadData", Key = (byte)0x03)]
public class ModbusDataCommand : ICommand<RtuSession, XphPackage>
{
    public async void Execute(RtuSession session, XphPackage package)
    {
        session.Logger.LogInformation($"远端设备:{session.RemoteEndPoint},地址:{package.Address},上报数据{BitConverter.ToString(package.Body).Replace("-", " ")}");
        session.Address = package.Address;

        var dataLength = 2; //单个通道数据区大小
        var channelCount = package.Length / dataLength;
        DeviceInfo deviceInfo = new DeviceInfo();
        deviceInfo.DeviceId = package.Address;
        for (int i = 0; i < channelCount; i++)
        {
            var data = new byte[dataLength];
            Array.Copy(package.Body, i * 2, data, 0, dataLength);
            var result = ConvertHexTemperatureToDecimal(data);
            if (result.HasValue)
            {
                DeviceChannel channel = new DeviceChannel
                {
                    Channel = i,
                    AorM = 0,
                    ErrorCode = 0,
                    Status = 0,
                    Value = result.Value,
                };
                deviceInfo.Channels.Add(channel);
            }
        }
    }

    public double? ConvertHexTemperatureToDecimal(byte[] hexTemperature)
    {
        //根据协议7F FF 表示未接传感器。 则返回null;
        if (hexTemperature.Length != 2 || hexTemperature[0] == 0x7F && hexTemperature[1] == 0xFF)
        {
            return null;
        }
        // 将十六进制温度编码转换为整数
        int temperatureValue = ConvertBytesToBigEndianInt(hexTemperature);

        // 检查二进制的第一位，判断正负
        if ((temperatureValue & 0x8000) != 0)
        {
            // 温度为负数，进行转换
            temperatureValue = -((temperatureValue ^ 0xFFFF) + 1);
        }

        // 转换为十进制并除以10
        double decimalTemperature = temperatureValue / 10.0;
        return decimalTemperature;
    }


    static int ConvertBytesToBigEndianInt(byte[] bytes)
    {
        int value = 0;
        for (int i = 0; i < bytes.Length; i++)
        {
            value = value << 8 | bytes[i];
        }
        return value;
    }
}
